PROJECT = firmware

OUT_DIR = output

C_SRCS := $(wildcard bsp/*.c) $(wildcard app/*.c)
A_SRCS := $(wildcard bsp/*.S)

RISCV_CC   := /opt/apps/riscv-none-gcc/7.2.0-4-20180606-1631/bin/riscv-none-embed-gcc
RISCV_GDB  := /opt/apps/riscv-none-gcc/7.2.0-4-20180606-1631/bin/riscv-none-embed-gdb
RISCV_SIZE := /opt/apps/riscv-none-gcc/7.2.0-4-20180606-1631/bin/riscv-none-embed-size
RISCV_DUMP := /opt/apps/riscv-none-gcc/7.2.0-4-20180606-1631/bin/riscv-none-embed-objdump

# RISCV_CC   := riscv64-elf-gcc
# RISCV_GDB  := riscv64-elf-gdb
# RISCV_SIZE := riscv64-elf-size
# RISCV_DUMP := riscv64-elf-objdump

OPENOCD    := ../openocd/src/openocd

INCLUDES := -I./bsp -I./app

CFLAGS := -O1
CFLAGS += -DUSE_PLIC -DUSE_M_TIME
CFLAGS += -g -march=rv32imac -mabi=ilp32 -mcmodel=medany
CFLAGS += -ffunction-sections -fdata-sections -fno-builtin-printf -fno-builtin-malloc
CFLAGS += $(INCLUDES)

LDFLAGS := -T./link.lds
LDFLAGS += -nostartfiles -Wl,--gc-sections -Wl,--wrap=scanf -Wl,--wrap=malloc -Wl,--wrap=printf
LDFLAGS += -Wl,--check-sections

C_OBJS := $(patsubst %.c, $(OUT_DIR)/%.o, $(C_SRCS))
A_OBJS := $(patsubst %.S, $(OUT_DIR)/%.o, $(A_SRCS))

GDB_UPLOAD_CMDS := --batch
GDB_UPLOAD_CMDS += -ex "set remotetimeout 240"
GDB_UPLOAD_CMDS += -ex "target extended-remote localhost:3333"
GDB_UPLOAD_CMDS += -ex "monitor reset halt"
GDB_UPLOAD_CMDS += -ex "monitor flash protect 0 64 last off"
GDB_UPLOAD_CMDS += -ex "load"
GDB_UPLOAD_CMDS += -ex "monitor resume"
GDB_UPLOAD_CMDS += -ex "monitor shutdown"
GDB_UPLOAD_CMDS += -ex "quit"

all: SIZE DUMP

SIZE: $(PROJECT).elf
	$(RISCV_SIZE) $^

DUMP: $(PROJECT).elf
	$(RISCV_DUMP) -D $^ > $(OUT_DIR)/$^.ASM

$(PROJECT).elf: $(A_OBJS) $(C_OBJS)
	$(RISCV_CC) $^ $(CFLAGS) $(LDFLAGS) -o $@

$(OUT_DIR)/%.o: %.c
	@mkdir -p $(dir $@)
	$(RISCV_CC) $(CFLAGS) -include sys/cdefs.h -c $^ -o $@

$(OUT_DIR)/%.o: %.S
	@mkdir -p $(dir $@)
	$(RISCV_CC) $(CFLAGS) -c $^ -o $@

upload: $(PROJECT).elf
	$(OPENOCD) -f openocd.cfg &
	$(RISCV_GDB) $^ $(GDB_UPLOAD_CMDS)

clean:
	rm -rf $(OUT_DIR) $(PROJECT).elf

run_openocd:
	$(OPENOCD) -f openocd.cfg

.PHONY: clean run_openocd
